﻿/// <reference path="P3.Core.Init.js" />
/// <reference path="P3.Core.js" />
/// <reference path="P3.Core.Settings.js" />
/// <reference path="P3.Core.SPClientJQuery.js" />
/// <reference path="jquery.fabric.min.js" />
/// <reference path="JQuery/jquery-ui.min.js" />
/// <reference path="JQuery/jquery.min.js" />


var messageDialog;
var FeatureScope = { Site: 0, Web: 1, List: 2, ContenType: 3 }

/* Error Dialog, Waiting dialog for long running operations */
function startLongRunningOperation(title, txt) {
    if (messageDialog != null) {
        messageDialog.close();
        messageDialog == null;
    }
    if (txt == "" || txt == null)
        txt = 'Please wait while request is in progress...';
    if (title == "" || title == null)
        title = 'Processing...';
    messageDialog = SP.UI.ModalDialog.showWaitScreenWithNoClose(title, txt, 76, 330);
}

function removeDialog() {
    if (messageDialog != null) {
        messageDialog.close();
        messageDialog = null;
    }
}

function showMessage(message, error) {
    removeDialog();
    var image;
    if (error) {
        image = "/_layouts/images/erroricon.png";
    } else {
        image = "/_layouts/images/TPDL.gif";
    }
    var div = document.createElement('div');
    div.innerHTML = '<div><img src=\'' + image + '\' style=\'float:left;margin-top:20px;margin-left:5px;\'><span style=\'float:left;margin-top:25px;margin-left:10px;margin-right:5px;width:260px\'>' + message + '</span></div>';
    var options = {
        title: "Error",
        height: 76,
        width: 330,
        html: div
    };
    SP.UI.ModalDialog.showModalDialog(options);
}


/* Get and set SharePoint Form Fields */
function setLookupFromFieldName(fieldName, value) {
    if (value == undefined) return;
    var theSelect = getTagFromIdentifierAndTitle("select", "Lookup", fieldName);
    // if theSelect is null, it means that the target list has more than
    // 20 items, and the Lookup is being rendered with an input element
    if (theSelect == null) {
        var theInput = getTagFromIdentifierAndTitle("input", "", fieldName);
        ShowDropdown(theInput.id); //this function is provided by SharePoint 
        var opt = document.getElementById(theInput.opt);
        setSelectedOption(opt, value);
        OptLoseFocus(opt); //this function is provided by SharePoint 
    } else {
        setSelectedOption(theSelect, value);
    }
}


//get the tag based on the the title/tagname
function getTagFromIdentifierAndTitle(tagName, identifier, title) {
    var len = identifier.length;
    var tags = document.getElementsByTagName(tagName);
    for (var i = 0; i < tags.length; i++) {
        var tempString = tags[i].id;
        if (tags[i].title == title && (identifier == "" || tempString.indexOf(identifier) == tempString.length - len)) {
            return tags[i];
        }
    }
    return null;

}

function getPickerInputElement(fieldsInternalName) {
    var result = "";
    var divs = document.getElementsByTagName("DIV");
    for (var i = 0; i < divs.length; i++) {
        if (divs[i].id == "WebPartWPQ2") {
            var tds = divs[i].getElementsByTagName("TD");
            for (var j = 0; j < tds.length; j++) {
                var cellHTML = tds[j].innerHTML;
                if (cellHTML.indexOf('FieldInternalName="' + fieldsInternalName + '"') >= 0) {
                    var innerDivs = tds[j].getElementsByTagName("DIV");
                    for (var k = 0; k < innerDivs.length; k++) {
                        if (innerDivs[k].id.indexOf("UserField_upLevelDiv") > 0) {
                            result = innerDivs[k];
                            break;
                        }
                    }
                }
            }

        }

    }
    return result;
}


function setPickerValue(fieldInternalName, value) {
    var picker = getPickerInputElement(fieldInternalName);
    picker.innerHTML = value;
}


/* Copy files */

function CopyOperation(destinationListTitle) {
    var context = SP.ClientContext.get_current();
    var web = context.get_web();
    context.load(web);
    var _destinationlib = web.get_lists().getByTitle(destinationList);
    context.load(_destinationlib);
    var notifyId;
    var currentlibid = SP.ListOperation.Selection.getSelectedList();
    var currentLib = web.get_lists().getById(currentlibid);
    var selectedItems = SP.ListOperation.Selection.getSelectedItems(context);
    var count = CountDictionary(selectedItems);

    for (var i in selectedItems) {
        var currentItem = currentLib.getItemById(selectedItems[i].id);
        context.load(currentItem);
        var File = currentItem.get_file();
        context.load(File);
        //Excecuting executeQueryAsync to get the loaded values
        context.executeQueryAsync(
function (sender, args) {
    if (File != null) {
        var _destinationlibUrl = web.get_serverRelativeUrl() + _destinationlib.get_title() + '/' + File.get_name();
        File.copyTo(_destinationlibUrl, true);
        notifyId = SP.UI.Notify.addNotification('Moving file…' + File.get_serverRelativeUrl() + 'to' + _destinationlibUrl, true);
        context.executeQueryAsync(
            function (sender, args) {
                showMessage('File copied successfully', false);
            },
            function (sender, args) {
                showMessage(args.get_message(), true);
            });
    }
},
            function (sender, args) {
                showMessage(args.get_message(), true);
            }
        );
    }
}


// wrapper which ensures SP.UI.Dialog.js is loaded before re-size fires.
// (if you need to trigger a re-size in your init scripts as the JS library is loaded asyncronously)
function resizeModalDialog() {
    SP.SOD.executeOrDelayUntilScriptLoaded(_resizeModalDialog, 'sp.ui.dialog.js');
}

function _resizeModalDialog() {
    // get the top-most dialog
    var dlg = SP.UI.ModalDialog.get_childDialog();

    if (dlg != null) {
        // dlg.$S_0 - is dialog maximized
        // dlg.get_$Z_0() - is dialog a modal
        if (!dlg.$S_0 && dlg.get_$Z_0()) {
            // resize the dialog
            dlg.autoSize();

            var xPos, yPos, //x & y co-ordinates to move modal to...
      win = SP.UI.Dialog.get_$1(), // the very bottom browser window object
      xScroll = SP.UI.Dialog.$24(win), // browser x-scroll pos
      yScroll = SP.UI.Dialog.$26(win); // browser y-scroll pos

            //SP.UI.Dialog.$1d(win) - get browser viewport width
            //SP.UI.Dialog.$1c(win) - get browser viewport height
            //dlg.$2_0 - modal's DOM element

            // caculate x-pos based on viewport and dialog width
            xPos = ((SP.UI.Dialog.$1d(win) - dlg.$2_0.offsetWidth) / 2) + xScroll;

            // if x-pos is out of view (content too wide), re-position to left edge + 10px
            if (xPos < xScroll + 10) {
                xPos = xScroll + 10;
            }

            // caculate y-pos based on viewport and dialog height
            yPos = ((SP.UI.Dialog.$1c(win) - dlg.$2_0.offsetHeight) / 2) + yScroll;

            // if x-pos is out of view (content too high), re-position to top edge + 10px
            if (yPos < yScroll + 10) {
                yPos = yScroll + 10;
            }

            // store dialog's new x-y co-ordinates
            dlg.$T_0 = xPos;
            dlg.$U_0 = yPos;

            // move dialog to x-y pos
            dlg.$m_0(dlg.$T_0, dlg.$U_0);

            // set dialog title bar text width
            //dlg.$H_0 - dialog title text SPAN
            //dlg.$6_0 - dialog title bar
            dlg.$H_0.style.width = Math.max(dlg.$6_0.offsetWidth - 64, 0) + 'px';

            // size down the dialog width/height if it's larger than browser viewport
            dlg.$2B_0();
        }
    }
}

function getCurrentItem(success, error) {
    var context = SP.ClientContext.get_current();
    var web = context.get_web();
    var listId = _spPageContextInfo.pageListId;
    var itemId = parseInt(GetUrlKeyValue('ID'));

    var list = web.get_lists().getById(_spPageContextInfo.pageListId);
    var listItem = list.getItemById(itemId);
    context.load(listItem);

    context.executeQueryAsync(
   function () {
       success(listItem);
   },
   error
  );
}

function getCurrentItem(success, error) {
    var context = SP.ClientContext.get_current();
    var web = context.get_web();
    var listId = _spPageContextInfo.pageListId;
    var itemId = parseInt(GetUrlKeyValue('ID'));
    var list = web.get_lists().getById(_spPageContextInfo.pageListId);
    var listItem = null;
    if (!isNaN(itemId)) {
        listItem = list.getItemById(itemId);
    } else {
        listItem = web.getFileByServerRelativeUrl("/" + getUrlParts(document.URL).pathname).get_listItemAllFields();
    }
    context.load(listItem);
    context.executeQueryAsync(
   function () {
       success(listItem);
   },
   error
  );
}

//gets all the property bag values from current web -KSI
function getCurrentWebProperties(success, error) {

    var clientContext;
    var web;
    var webProperties;

    clientContext = new SP.ClientContext.get_current(); //create client context
    web = clientContext.get_web(); //get web
    webProperties = web.get_allProperties(); //get all web properties
    clientContext.load(webProperties); //load properties
    clientContext.executeQueryAsync(function () { success(webProperties); }, error);
}

//gets a specific value from the property bag based on the key --KSI
function getWebProperty(success, error, propertyKey) {
    var key = propertyKey;
    getCurrentWebProperties(function (props) {
        try {
            var value = props.get_fieldValues()[key];
            success(value);
        } catch (e) {
            error(e);
        }
    }, function (err) { error(err); });
}

//set a property bag value -KSI
function setWebProperty(success, error, propertyKey, PropertyVal) {

    var clientContext;
    var web;
    var webProperties;

    clientContext = new SP.ClientContext.get_current(); //create client context
    web = clientContext.get_web(); //get web
    webProperties = web.get_allProperties(); //get all web properties
    webProperties.set_item(propertyKey, PropertyVal);
    web.update();
    clientContext.load(webProperties); //load properties
    clientContext.executeQueryAsync(function () { success("success"); }, error);
}

//find active View Id -KSI
function getCurrentViewId(listId) {
    var viewId = '';
    for (var ctxKey in g_ctxDict) {
        var curCtx = g_ctxDict[ctxKey];
        if (curCtx.listName.toLowerCase() == listId.toLowerCase()) {
            viewId = curCtx.view;
            break;
        }
    }
    return viewId;
}

//gets the current web id - KSI
function getCurrentWebId(success, error) {
    var ctx;
    var web;

    ctx = SP.ClientContext.get_current();
    web = ctx.get_web();
    ctx.load(web);
    ctx.executeQueryAsync(
        function () {
            var webId = web.get_id();
            success(webId.toString());
        },
        function (sender, args) {
            error("failed: " + args.get_message());
        }
    );
}


//checks if the user belongs to a specific group --KSI
function IsCurrentUserMemberOfGroup(strGroupName, functionComplete) {

    //Setup Vars
    currentContext = null;
    currentWeb = null;
    allGroups = null;
    leaderGroup = null;
    currentUser = null;
    groupUsers = null;

    //Get an instance of the Client Content.
    currentContext = new SP.ClientContext.get_current();

    //Grab the client web object.
    currentWeb = currentContext.get_web();

    //Get the current user object
    currentUser = currentContext.get_web().get_currentUser();
    currentContext.load(currentUser);

    //Setup the groupColletion.
    allGroups = currentWeb.get_siteGroups();
    currentContext.load(allGroups);

    //Now populate the objects above.
    currentContext.executeQueryAsync(
        Function.createDelegate(this, GetAllGroupsExecuteOnSuccess),
        Function.createDelegate(this, ExecuteOnFailure)
    );

    // GroupCollection - Load - SUCCESS
    function GetAllGroupsExecuteOnSuccess(sender, args) {

        // CHECK THE GROUPS
        // Time to Enumerate through the group collection that was returned.
        var groupEnumerator = allGroups.getEnumerator();

        // Loop for the collection.
        while (groupEnumerator.moveNext()) {

            //Grab the Group Item.
            var group = groupEnumerator.get_current();
            if (group.get_title().indexOf(strGroupName) > -1) {

                // Now that we have the group let's grab the list of users.
                groupUsers = group.get_users();
                currentContext.load(groupUsers);
                currentContext.executeQueryAsync(
                    Function.createDelegate(this, SingleGroupExecuteOnSuccess),
                    Function.createDelegate(this, ExecuteOnFailure)
                );
            }
        }
    }

    // Single Group - Load - SUCCESS
    function SingleGroupExecuteOnSuccess(sender, args) {

        // Time to setup the Enumerator
        var groupUserEnumerator = groupUsers.getEnumerator();

        // This is the flag to set to true if the user is in the group.
        var boolUserInGroup = false;

        // and start looping.
        while (groupUserEnumerator.moveNext()) {

            //Grab the User Item.
            var groupUser = groupUserEnumerator.get_current();

            // and finally. If a Group User ID Matches the current user ID then they are in the group!
            if (groupUser.get_id() == currentUser.get_id()) {
                boolUserInGroup = true;
            }
        }

        //Run the delegate function with the bool;
        functionComplete(boolUserInGroup);
    }

    // GroupCollection or Single Group - Load - FAILURE
    function ExecuteOnFailure(sender, args) {
        //Run the delegate function and return false because there was no match.
        functionComplete(false);
    }
}

function spFieldManager() {

    //private method
    var baseFunction = function (title, type) {
        var tds = $(".ms-formtable").find("td.ms-formbody");
        var nonReq;
        var req;
        switch (type.toLowerCase()) {
            case "date":
            case "checkbox":
            case "text":
                nonReq = $(tds).find("input[title='" + title + "']").first();
                req = $(tds).find("input[title='" + title + " Required Field']").first();
                break;
            case "select":
                nonReq = $(tds).find("select[title='" + title + "']").first();
                req = $(tds).find("select[title='" + title + " Required Field']").first();
                break;
            case "textarea":
                nonReq = $(tds).find("textarea[title='" + title + "']").first();
                req = $(tds).find("textarea[title='" + title + " Required Field']").first();
                break;
            case "peoplepicker":
                $("div[title='People Picker']").each(function (i, e) {

                    var textVal = $(e).closest("span.ms-usereditor").
                        closest('td.ms-formbody').closest('tr').
                        find('.ms-standardheader').text().trim();

                    if (textVal == title + " *") {
                        req = $(e);
                    } else if (textVal == title) {
                        nonReq = $(e);
                    }
                });
                break;
            default: throw type + " Not supported by this function..";
                break;
        }

        if ($(req).length == 0) {
            req = null;
        }
        if ($(nonReq).length == 0) {
            nonReq = null;
        }

        return { requiredField: req, optionalField: nonReq };
    }

    this.checkUserInGroup = function (groupId, userId, callback) {

        this.ctx = new SP.ClientContext.get_current();
        this.group = this.ctx.get_web().get_siteGroups().getById(groupId);
        this.users = this.group.get_users();
        this.userId = userId;
        this.callback = callback;
        this.ctx.load(this.group);
        this.ctx.load(this.users);
        this.ctx.executeQueryAsync(
			Function.createDelegate(this, GroupUsersLoadSuccess),
    		Function.createDelegate(this, GroupUsersLoadFailed)
    	);

        function GroupUsersLoadSuccess(sender, args) {
            var usersEnum = this.users.getEnumerator();

            while (usersEnum.moveNext()) {
                var currentUser = usersEnum.get_current();

                if (currentUser.get_id() == this.userId) {
                    this.callback(true);
                    return;
                }
            }

            this.callback(false);
        }

        function GroupUsersLoadFailed(sender, args) {
            safeLogger(args.get_message());
        }
    }

    var getValidField = function (baseFuncResult) {
        try {
            if (baseFuncResult.requiredField != null) {
                return baseFuncResult.requiredField;
            }
        } catch (e) { safeLogger(e.get_Message()); throw e; }
        try {
            if (baseFuncResult.optionalField != null) {
                return baseFuncResult.optionalField;
            }
        } catch (e) { safeLogger(e.get_Message()); throw e; }
    }

    //public methods
    this.setFieldValue = function (title, type, value) {
        var field = baseFunction(title, type);
        var fieldToset = getValidField(field);

        $(fieldToset).val(value);
    }

    //public methods
    this.getFieldValue = function (title, type, value) {
        var field = baseFunction(title, type);
        var fieldToget = getValidField(field);

        return $(fieldToget).val();
    }

    this.setPeoplePickerValue = function (title, value) {
        var field = baseFunction(title, 'peoplepicker');
        var fieldToset = getValidField(field);

        $(fieldToset).text(value);
        $(fieldToset).closest('table.ms-usereditor').first().find("a[title='Check Names']").first().click();
    }

    this.getPeoplePickerValue = function (title) {
        var field = baseFunction(title, 'peoplepicker');
        var fieldToget = getValidField(field);

        return $(fieldToget).text().trim();
    }

    this.getField = function (title, type) {
        var field = baseFunction(title, type);
        var fieldToget = getValidField(field);

        return fieldToget;
    }

    this.hideField = function (title, type) {
        var field;
        var fieldToget;

        field = baseFunction(title, type);
        fieldToget = getValidField(field);

        if (type.toLowerCase() == "date") {
            $(fieldToget).closest("table").closest("tr").hide();
        } else {
            $(fieldToget).closest("tr").hide();
        }
    }

    this.showField = function (title, type) {
        var field;
        var fieldToget;

        field = baseFunction(title, type);
        fieldToget = getValidField(field);

        if (type.toLowerCase() == "date") {
            $(fieldToget).closest("table").closest("tr").show();
        } else {
            $(fieldToget).closest("tr").show();
        }
    }

    this.getWorkflowId = function (listId, workflowName, callback) {
        var ctx = new SP.ClientContext.get_current();
        var list = ctx.get_web().get_lists().getById(listId);
        this.wfAssociations = list.get_workflowAssociations();
        this.callback = callback;
        this.workflowName = workflowName;
        ctx.load(this.wfAssociations);
        ctx.executeQueryAsync(
		    Function.createDelegate(this, workflowAssociationsLoadSuccess),
		    Function.createDelegate(this, workflowAssociationsLoadFailed)
	    );
    }

    function workflowAssociationsLoadSuccess(sender, args) {
        var wfEnum = this.wfAssociations.getEnumerator();
        while (wfEnum.moveNext()) {
            var curWorkflow = wfEnum.get_current();
            if (curWorkflow.get_name().toLowerCase() == this.workflowName.toLowerCase()) {
                this.callback(curWorkflow.get_id().toString());
                return;
            }
        }
        this.callback('');
    }

    function workflowAssociationsLoadFailed(sender, args) {
        safeLogger(args.get_message());
    }
}


//pass in the web part ID as a string (guid)
function getWebPartProperties(wpId, pageUrl) {

    var dfd = $.Deferred();
    //get the client context 
    var clientContext =
        new SP.ClientContext(_spPageContextInfo.webServerRelativeUrl);
    //get the current page as a file 
    var oFile = clientContext.get_web().getFileByServerRelativeUrl(pageUrl);
    //get the limited web part manager for the page 
    var limitedWebPartManager = oFile.getLimitedWebPartManager(SP.WebParts.PersonalizationScope.shared);
    //get the web parts on the current page 
    var collWebPart = limitedWebPartManager.get_webParts();
    //request the web part collection and load it from the server 
    clientContext.load(collWebPart);
    clientContext.executeQueryAsync(Function.createDelegate(this, function () {
        var webPartDef = null;
        //find the web part on the page by comparing ID's 
        for (var x = 0; x < collWebPart.get_count() && !webPartDef; x++) {
            var temp = collWebPart.get_item(x);
            if (temp.get_id().toString() === wpId) {
                webPartDef = temp;
            }
        }
        //if the web part was not found 
        if (!webPartDef) {
            dfd.reject("Web Part: " + wpId + " not found on page: "
                + _spPageContextInfo.webServerRelativeUrl);
            return;
        }
        //get the web part properties and load them from the server 
        var webPartProperties = webPartDef.get_webPart().get_properties();
        clientContext.load(webPartProperties);
        clientContext.executeQueryAsync(Function.createDelegate(this, function () {
            dfd.resolve(webPartProperties, webPartDef, clientContext);
        }), Function.createDelegate(this, function () {
            dfd.reject("Failed to load web part properties");
        }));
    }), Function.createDelegate(this, function () {
        dfd.reject("Failed to load web part collection");
    }));
    return dfd.promise();
}

//pass in the web part ID and a JSON object with the properties to update 
function saveWebPartProperties(wpId, obj, pageUrl) {
    var dfd = $.Deferred();
    getWebPartProperties(wpId, pageUrl).done(
        function (webPartProperties, webPartDef, clientContext) {
            //set web part properties 
            for (var key in obj) {
                webPartProperties.set_item(key, obj[key]);
            }
            //save web part changes 
            webPartDef.saveWebPartChanges();
            //execute update on the server 
            clientContext.executeQueryAsync(Function.createDelegate(this, function () {
                dfd.resolve();
            }), Function.createDelegate(this, function () {
                dfd.reject("Failed to save web part properties");
            }));
        }).fail(function (err) { dfd.reject(err); });
    return dfd.promise();
}



function executeDeferred(ctx, dfd, returnValue) {
    ctx.executeQueryAsync(
	        Function.createDelegate(this, function () {
	            dfd.resolve(returnValue);
	        }),
	        Function.createDelegate(this, function (sender, args) {
	            dfd.reject(args.get_message());
	        })
	    );
}


function setJSLinkForAllViews(webServerRelativeSiteUrl, jsLink) {
    var dfd = $.Deferred();
    var clientContext = new SP.ClientContext(webServerRelativeSiteUrl);
    var lists;
    var listCount = 0;
    var viewCount;
    executeFunctionForClientObject(clientContext, clientContext.get_web(), 'get_lists', '', 'Title').done(function (lists) {
        var listEnumerator = lists.getEnumerator();
        while (listEnumerator.moveNext()) {
            var list = listEnumerator.get_current();
            executeFunctionForClientObject(clientContext, listEnumerator.get_current(), 'get_views', '').done(function (views) {
                viewCount = 0;
                listCount++;
                var viewEnumerator = views.getEnumerator();
                while (viewEnumerator.moveNext()) {
                    var view = viewEnumerator.get_current();
                    executeFunctionForClientObject(clientContext, view, 'set_jsLink', jsLink).done(function () {
                        viewCount++;
                        if (listCount == lists.get_count() && (viewCount == views.get_count()))
                            dfd.resolve();
                    }).fail(function (error) {
                        dfd.reject(error);
                    });
                }
            }).fail(function (error) {
                dfd.reject(error)
            });
        }
    }).fail(function (error) {
        dfd.reject(error)
    });
    return dfd.promise();
}

function setJSLinkForSiteField(webServerRelativeSiteUrl, fieldInternalNameOrTitle, jsLink) {
    var clientContext = new SP.ClientContext(webServerRelativeSiteUrl);
    var fields = clientContext.get_web().get_availableFields();
    var field = fields.getByInternalNameOrTitle(fieldInternalNameOrTitle);
    executeFunctionForClientObject(clientContext, field, 'set_jsLink', jsLink);
}

function setJSLinkForListField(webServerRelativeSiteUrl, listId, fieldInternalNameOrTitle, jsLink) {
    var clientContext = new SP.ClientContext(webServerRelativeSiteUrl);
    var list = clientContext.get_web().get_lists().getById(listId);
    var fields = list.get_fields();
    var field = fields.getByInternalNameOrTitle(fieldInternalNameOrTitle);
    executeFunctionForClientObject(clientContext, field, 'set_jsLink', jsLink);
}

// Execute any  function on a ClientObject. result will be an array
// Example executeFunctionForClientObject(clientContext, fieldcollection, 'set_jsLink', jsLink, 'Title,Status').done(function(result, fieldcollection){ ..do sth with result and fieldcollection }).fail(function(error){alert(error)});
function executeFunctionForClientObject(ctx, clientObject, functionName, functionParameter, commaSeparatedPropertiesToLoad) {
    var dfd = $.Deferred();
    var returnValue;
    if ((functionParameter == null) || (functionParameter == ''))
        returnValue = clientObject[functionName]();
    else
        returnValue = clientObject[functionName](functionParameter);
    if (returnValue instanceof Object) {
        if ((commaSeparatedPropertiesToLoad == null) || (commaSeparatedPropertiesToLoad == ''))
            ctx.load(returnValue);
        else
            ctx.load(returnValue, commaSeparatedPropertiesToLoad);
    }
    if (functionName.startsWith('set'))
        clientObject.update();
    ctx.executeQueryAsync(
        Function.createDelegate(this, function () {
            dfd.resolve(returnValue, clientObject);
        },
        Function.createDelegate(this, function (sender, args) {
            dfd.reject(args.get_message());
        }
    )));
    return dfd.promise();
}


// Execute any  function on a collection of ClientObjects
// Example executeFunctionForClientObjectCollection(clientContext, field, 'set_jsLink', jsLink, 'Title,Status').done(function(result, field){ ..do sth with result and field }).fail(function(error){alert(error)});
function executeFunctionForClientObjectCollection(ctx, clientObjectCollection, functionName, functionParameter, commaSeparatedPropertiesToLoad) {
    var dfd = $.Deferred();
    var collectionEnumerator = clientObjectCollection.getEnumerator();
    var results = [];
    var executeCount = 0;
    if ((clientObjectCollection == null) || (clientObjectCollection.get_count() == 0))
        dfd.resolve(results, clientObjectCollection, tmp);
    else {
        while (collectionEnumerator.moveNext()) {
            var clientObject = collectionEnumerator.get_current();
            executeFunctionForClientObject(ctx, clientObject, functionName, functionParameter, commaSeparatedPropertiesToLoad).done(function (result) {
                executeCount++;
                results.push(result);
                if (executeCount == clientObjectCollection.get_count())
                    dfd.resolve(results, clientObjectCollection);
            }
            ).fail(function (error) {
                dfd.reject(error);
            }
            );
        }
    }
    return dfd.promise();
}


function createfile(textContent, nameWithExtension, folderObject, success, error) {
    var fileCreateInfo;
    fileCreateInfo = new SP.FileCreationInformation();
    fileCreateInfo.set_url(name);
    fileCreateInfo.set_content(new SP.Base64EncodedByteArray());
    for (var i = 0; i < textContent.length; i++) {
        fileCreateInfo.get_content().append(textContent.charCodeAt(i));
    }
    this.newFile = folder.get_files().add(fileCreateInfo);
    clientContext.load(this.newFile);
    clientContext.executeQueryAsync(
		Function.createDelegate(this, success),
		Function.createDelegate(this, error)
	);
}

// Create Textfile. filePath should be without slash at the end
function createFile(ctx, fileContent, filePath, fileName) {
    var dfd = $.Deferred();
    var fileCreateInfo;
    var web = ctx.get_web();
    executeFunctionForClientObject(ctx, web, "getFileByServerRelativeUrl", filePath + "/" + fileName, "CheckOutType").done(function (txtFile) {
        var checkedOut;
        if (txtFile.get_checkOutType() == SP.CheckOutType.none) {
            txtFile.checkOut();
            checkedOut = true;
        } else
            if ((txtFile.get_checkOutType() == SP.CheckOutType.online) || (txtFile.get_checkOutType() == SP.CheckOutType.offline))
                checkedOut = true;
            else
                checkedOut = false;
        var destFolder = web.getFolderByServerRelativeUrl(filePath);
        fileCreateInfo = new SP.FileCreationInformation();
        fileCreateInfo.set_url(fileName);
        fileCreateInfo.set_content(new SP.Base64EncodedByteArray());
        fileCreateInfo.set_overwrite(true);
        for (var i = 0; i < fileContent.length; i++) {
            fileCreateInfo.get_content().append(fileContent.charCodeAt(i));
        }
        this.existingFile = destFolder.get_files().add(fileCreateInfo);
        if (checkedOut)
            this.existingFile.checkIn();
        ctx.load(this.existingFile);
        ctx.executeQueryAsync(
            Function.createDelegate(this, function (sender, args) { dfd.resolve(sender, this.existingFile); }),
            Function.createDelegate(this, function (sender, args) { dfd.reject(args); })
        );
    });
    return dfd.promise();
}

// Make a Webrequest
function AllBrowserWebRequest() {
    var xmlHttp;
    try {
        xmlHttp = new XMLHttpRequest();
    } catch (e) {
        try {
            xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
        } catch (e) {
            try {
                xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
            } catch (e) {
                alert("Your browser does not support AJAX!");
                return false;
            }
        }
    }
    return xmlHttp;
}

var user;
var membersGroup;
function addUser2Members(groupId) {
     var clientContext = new SP.ClientContext();
     var groupCollection = clientContext.get_web().get_siteGroups();
     // Get the members group, assuming its ID is 5.
     membersGroup = groupCollection.getById(groupId);
     user = clientContext.get_web().get_currentUser();
     var userCollection = membersGroup.get_users();
     userCollection.addUser(user);
     clientContext.load(user);
     clientContext.load(membersGroup);
     clientContext.executeQueryAsync(Function.createDelegate(this, this.onQueryAddMemSucceeded), Function.createDelegate(this, this.onQueryAddMemFailed));
}
function onQueryAddMemSucceeded() {
    alert(' Congratulations!' + '\n \n ' + user.get_title() + ' \n \n' + ' Has successfully joined the SharePoint Group:' + '\n \n ' + membersGroup.get_title());
    SP.UI.ModalDialog.RefreshPage(SP.UI.DialogResult.OK);
}
function onQueryAddMemFailed(sender, args) {
    alert('Request failed. ' + args.get_message() + '\n' + args.get_stackTrace());
}

